var ComponentPage = function(){
	this.menu_name = 'Components';
}

ComponentPage.prototype.Refresh = function(){
	this.PopulateComponents();
}

ComponentPage.prototype.PopulateComponents = function(){
	$('div#income').empty();
	$('div#expense').empty();
	$('div#saving').empty();
	$.map(CreateColumnElements(window.income, income_model), function($element){
		$element.appendTo($('div#income'));
	});
	$.map(CreateColumnElements(window.expense, expense_model), function($element){
		$element.appendTo($('div#expense'));
	});
	$.map(CreateColumnElements(window.saving, saving_model), function($element){
		$element.appendTo($('div#saving'));
	});
}

ComponentPage.prototype.EditElement = function(id){
	var data = FindDataAndModelByID(id);
	$('div#'+id).replaceWith(CreateEditableElement(data.data, data.model));
}

ComponentPage.prototype.SaveData = function(id){
	console.log('Saving Data: '+id);
	var data = FindDataAndModelByID(id);
	UpdateBrowserData(id);
	$.post('/save_instance', {type:data.model.GetName(), data:data.data}, function(data){}, 'json');
	
	$('div#'+id).replaceWith(CreateStaticElement(data.data, data.model));
}

ComponentPage.prototype.CancelEdit = function(id){
	var data = FindDataAndModelByID(id);
	$('div#'+id).replaceWith(CreateStaticElement(data.data, data.model));
}

ComponentPage.prototype.CreateNewElement = function(type){
	var promise = $.getJSON('/request_new_instance', {type:type});
	promise.done(function(instance){
		window[type].push(instance);
		var $element = CreateEditableElement(instance, models[type]).appendTo($('div#'+type));
		$element.find('a#cancel').attr('onclick', 'components.DiscardNewElement("'+instance._id+'")');
	});
	return false;
}

ComponentPage.prototype.DeleteElement = function(id, type){
	$('div#'+id).remove();
	RemoveDataByID(id);
	$.post('/delete_instance', {id:id, type:type});
	return false;
}

ComponentPage.prototype.DiscardNewElement = function(id){
	RemoveDataByID(id);
	$('div#'+id).remove();
}

// PRIVATE FUNCTIONS
function CreateColumnElements(datas, model){
	return $.map(datas, function(data){ return CreateStaticElement(data, model); })
}

function CreateEditableElement(data, model){
	var $element = $('<div></div>').attr('id', data._id);
	
	$.each(model, function(key, item){		
		if(key == 'id' || typeof item == 'function'){ return; }
		
		$element.append(item.display_name+': ');
		
		if(item.type == 'text' || item.type == 'number'){
			$('<input />').appendTo($element).attr('id', key).val(data[key]);
		}
		else if(item.type =='frequency'){
			var $drop_down = $('<select></select>').appendTo($element).attr('id', key);
			$.each(frequencies, function(days, name){
				$('<option></option>').appendTo($drop_down).attr('value', days).html(name);
			});
			$drop_down.val(data[key]);
		}
		$element.append('<br>');
	});
	$('<a href="#">Save</a>').appendTo($element).attr('onclick', 'components.SaveData("'+data._id+'")').attr('id', 'save');
	$element.append(' or ');
	$('<a href="#">Cancel</a>').appendTo($element).attr('onclick', 'components.CancelEdit("'+data._id+'")').attr('id', 'cancel');
	$element.append('<br>');
	$element.append('<br>');
			
	return $element;
}

function CreateStaticElement(data, model){
	var $element = $('<div></div>').attr('id', data._id);
	
	$.each(model, function(key, item){
		if(key == 'id' || typeof item == 'function'){ return; }
		
		$element.append(item.display_name+': ');
		
		if(item.type == 'text' || item.type == 'number'){
			$('<span></span>').appendTo($element).attr('id', key).html(data[key]);
		}
		else if(item.type =='frequency'){
			$('<span></span>').appendTo($element).attr('id', key).html(frequencies[data[key]]);
		}
		$element.append('<br>');
	});
	$('<a href="#">Edit</a>').appendTo($element).attr('onclick', 'components.EditElement("'+data._id+'")');
	$element.append(' or ');
	$('<a href="#">Delete</a>').appendTo($element).attr('onclick', 'components.DeleteElement("'+data._id+'", "'+model.GetName()+'")');
	$element.append('<br>');
	$element.append('<br>');
			
	return $element;
}

function UpdateBrowserData(id){
	var res = FindDataAndModelByID(id);
	var data = res.data;
	var model = res.model;
	var $element = $('div#'+id);
	
	$.each(model, function(key, desc){
		if(key == id || typeof desc == 'function'){ return; }
		
		data[key] = $element.find('#'+key).val();
	});
}

function FindDataAndModelByID(id){
	// @TODO seems like a crude way of finding the data
	var data = null;
	var model = null;
	
	for(var key in window.income){
		if(window.income[key]._id == id){
			data = window.income[key];
			model = income_model;
			break;
		}
	}
	if(data == null){
		for(var key in window.expense){
			if(window.expense[key]._id == id){
				data = window.expense[key];
				model = expense_model;
				break;
			}
		}
	}
	if(data == null){
		for(var key in window.saving){
			if(window.saving[key]._id == id){
				data = window.saving[key];
				model = saving_model;
				break;
			}
		}
	}
		
	return {data: data, model: model};
}

function RemoveDataByID(id){
	for(var key in window.income){
		if(window.income[key]._id == id){
			window.income.splice(key, 1);
			return;
		}
	}
	for(var key in window.expense){
		if(window.expense[key]._id == id){
			window.expense.splice(key, 1);
			return;
		}
	}
	for(var key in window.saving){
		if(window.saving[key]._id == id){
			window.saving.splice(key, 1);
			return;
		}
	}
}

var income_model = {
	id: {type: 'text', display_name: ''},
	name: {type: 'text', display_name: 'Name'},
	amount: {type: 'number', display_name: 'Amount'},
	frequency: {type: 'frequency', display_name: 'Frequency'},
	tax_rate: {type: 'number', display_name: 'Tax Rate'},
	NetDailyValue: function(data){
		return (data.amount/data.frequency)*(1-(data.tax_rate/100));
	},
	GetName: function(){ return 'income' }
};

var expense_model = {
	id: {type: 'text', display_name: ''},
	name: {type: 'text', display_name: 'Name'},
	amount: {type: 'number', display_name: 'Amount'},
	frequency: {type: 'frequency', display_name: 'Frequency'},
	NetDailyValue: function(data){
		return (data.amount/data.frequency);
	},
	GetName: function(){ return 'expense' }
};

var saving_model = {
	id: {type: 'text', display_name: ''},
	name: {type: 'text', display_name: 'Name'},
	goal: {type: 'number', display_name: 'Goal'},
	contribution: {type: 'number', display_name: 'Contribution'},
	frequency: {type: 'frequency', display_name: 'Frequency'},
	NetDailyValue: function(data){
		return (data.contribution/data.frequency);
	},
	GetName: function(){ return 'saving' }
};

var models = {};
models.income = income_model;
models.expense = expense_model;
models.saving = saving_model;

var frequencies = {
	1: 'Daily',
	7: 'Weekly',
	14: 'Fortnightly',
	30: 'Monthly',
	91: 'Quarterly',
	183: 'Semi-Anually',
	365: 'Anually'
};

